/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.chl.angholt.bookproject.db;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import edu.chl.angholt.bookproject.db.exception.*;
import java.lang.reflect.Method;

/**
 *
 * @author Jonas
 * Abstract base class for the controller classes
 */
public abstract class EntityJpaCtrl<T> implements IJpaCtrl<T> {

    protected static EntityManagerFactory emf;

    public EntityJpaCtrl(EntityManagerFactory emf) {
        EntityJpaCtrl.emf = emf;
    }

    /**
     * Persists the supplied entity to the database
     * @param t The entity to persist
     */
    @Override
    public void create(T t) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        tx.begin();
        em.persist(t);
        tx.commit();

        em.close();

    }

    /**
     * Merges an existing database entry with the supplied entity
     * @param t The entity to merge
     * @throws NonexistentEntityException If the entity is not in the database
     * @throws Exception 
     */
    @Override
    public void edit(T t) throws NonexistentEntityException, Exception {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        tx.begin();
        Method[] meth = t.getClass().getMethods();
        Long id = (long) -1;
        for(int i = 0; i<meth.length;i++){
            Class typ = meth[i].getReturnType();
            if(typ.isInstance(id)){
                id = (Long) meth[i].invoke(t, null);
                break;
            }
        }
        
        
        T result = (T)  em.find(t.getClass(),id);

        if (result == null) {
            throw new NonexistentEntityException("Can not update entity that does not exist");
        }

        em.merge(t);
        tx.commit();
        em.close();
    }

    @Override
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
    
    
    
}
